package com.petdog.module.pet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.petdog.common.dto.PageResult;
import com.petdog.common.util.FileUploadUtil;
import com.petdog.infrastructure.entity.Pet;
import com.petdog.infrastructure.mapper.PetMapper;
import com.petdog.infrastructure.mapper.UserCommunityMapper;
import com.petdog.module.pet.dto.PetCreateRequest;
import com.petdog.module.pet.dto.PetUpdateRequest;
import com.petdog.module.pet.dto.PetDetailResponse;
import com.petdog.module.pet.dto.PetListResponse;
import com.petdog.module.pet.service.PetService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 宠物服务实现类
 */
@Service
public class PetServiceImpl implements PetService {
    private static final Logger logger = LoggerFactory.getLogger(PetServiceImpl.class);
    
    @Autowired
    private PetMapper petMapper;
    
    @Autowired
    private UserCommunityMapper userCommunityMapper;
    
    @Autowired
    private FileUploadUtil fileUploadUtil;
    
    @Override
    @Transactional
    public Pet createPet(PetCreateRequest request, Long userId) {
        Pet pet = new Pet();
        BeanUtils.copyProperties(request, pet);
        pet.setUserId(userId);
        pet.setCreateTime(LocalDateTime.now());
        pet.setUpdateTime(LocalDateTime.now());
        
        // 验证宠物昵称（1-20字符，仅支持中文、英文、数字，无特殊符号）
        if (pet.getName() != null && !pet.getName().matches("[\\u4e00-\\u9fa5a-zA-Z0-9]{1,20}")) {
            throw new IllegalArgumentException("昵称必须为1-20字符，只能包含中文、英文和数字");
        }
        
        // 验证宠物性别（仅支持值 1 或 2）
        if (pet.getGender() != null && (pet.getGender() != 1 && pet.getGender() != 2)) {
            throw new IllegalArgumentException("性别只能是1或2");
        }
        
        // 插入宠物记录
        int result = petMapper.insert(pet);
        if (result != 1) {
            logger.error("创建宠物档案失败");
            throw new RuntimeException("创建宠物档案失败");
        }
        
        logger.info("用户ID: {} 创建宠物档案成功，宠物ID: {}", userId, pet.getPetId());
        
        return petMapper.selectById(pet.getPetId());
    }
    
    @Override
    public com.petdog.common.dto.PageResult<Pet> getUserPets(Long userId, int pageNum, int pageSize) {
        QueryWrapper<Pet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.orderByDesc("create_time");
        
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;
        
        // 查询总数
        long total = petMapper.selectCount(queryWrapper);
        
        // 分页查询
        queryWrapper.last("LIMIT " + offset + ", " + pageSize);
        List<Pet> pets = petMapper.selectList(queryWrapper);
        
        return new com.petdog.common.dto.PageResult<>(pets, pageNum, pageSize, total);
    }
    
    @Override
    public List<PetListResponse> getUserPets(Long userId) {
        // 验证参数
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        List<Pet> pets = petMapper.selectByUserId(userId);
        List<PetListResponse> responses = new ArrayList<>();
        
        for (Pet pet : pets) {
            PetListResponse response = new PetListResponse();
            BeanUtils.copyProperties(pet, response);
            responses.add(response);
        }
        
        return responses;
    }
    
    @Override
    public PetDetailResponse getPetDetail(Long petId, Long userId) {
        // 验证参数
        if (petId == null || userId == null) {
            throw new IllegalArgumentException("宠物ID或用户ID不能为空");
        }
        
        Pet pet = petMapper.selectById(petId);
        if (pet == null) {
            logger.warn("宠物ID: {} 不存在", petId);
            return null;
        }
        
        if (!pet.getUserId().equals(userId)) {
            logger.warn("用户ID: {} 无权访问宠物ID: {}", userId, petId);
            throw new SecurityException("无权限操作该宠物");
        }
        
        PetDetailResponse response = new PetDetailResponse();
        BeanUtils.copyProperties(pet, response);
        
        return response;
    }
    
    @Override
    @Transactional
    public Pet updatePet(Long petId, PetUpdateRequest request, Long userId) {
        // 验证参数
        if (petId == null || request == null || userId == null) {
            throw new IllegalArgumentException("宠物信息、宠物ID或用户ID不能为空");
        }
        
        // 检查宠物是否存在且属于该用户
        Pet existingPet = petMapper.selectById(petId);
        if (existingPet == null) {
            logger.warn("宠物ID: {} 不存在", petId);
            throw new IllegalArgumentException("宠物不存在");
        }
        
        if (!existingPet.getUserId().equals(userId)) {
            logger.warn("用户ID: {} 无权访问宠物ID: {}", userId, petId);
            throw new SecurityException("无权限操作该宠物");
        }
        
        // 验证宠物昵称（1-20字符，仅支持中文、英文、数字，无特殊符号）
        if (request.getName() != null && !request.getName().matches("[\\u4e00-\\u9fa5a-zA-Z0-9]{1,20}")) {
            throw new IllegalArgumentException("昵称必须为1-20字符，只能包含中文、英文和数字");
        }
        
        // 验证宠物性别（仅支持值 1 或 2）
        if (request.getGender() != null && (request.getGender() != 1 && request.getGender() != 2)) {
            throw new IllegalArgumentException("性别只能是1或2");
        }
        
        // 更新宠物信息
        Pet pet = new Pet();
        BeanUtils.copyProperties(request, pet);
        pet.setPetId(petId);
        pet.setUserId(userId); // 确保用户ID不会被修改
        pet.setUpdateTime(LocalDateTime.now());
        
        int result = petMapper.updateById(pet);
        if (result != 1) {
            logger.error("更新宠物信息失败，宠物ID: {}", petId);
            throw new RuntimeException("更新宠物信息失败");
        }
        
        logger.info("用户ID: {} 更新宠物信息成功，宠物ID: {}", userId, petId);
        
        return petMapper.selectById(petId);
    }
    
    @Override
    @Transactional
    public void deletePet(Long petId, Long userId) {
        // 验证参数
        if (petId == null || userId == null) {
            throw new IllegalArgumentException("宠物ID或用户ID不能为空");
        }
        
        // 检查宠物是否存在且属于该用户
        Pet pet = petMapper.selectById(petId);
        if (pet == null) {
            logger.warn("宠物ID: {} 不存在", petId);
            throw new IllegalArgumentException("宠物不存在");
        }
        
        if (!pet.getUserId().equals(userId)) {
            logger.warn("用户ID: {} 无权访问宠物ID: {}", userId, petId);
            throw new SecurityException("无权限操作该宠物");
        }
        
        // 检查是否存在未完成业务（如订单、社交匹配）
        if (hasUnfinishedBusiness(petId)) {
            throw new IllegalStateException("宠物存在未完成业务，无法删除");
        }
        
        // 删除宠物照片
        if (pet.getAvatar() != null) {
            try {
                fileUploadUtil.deleteImage(pet.getAvatar());
            } catch (Exception e) {
                logger.warn("删除宠物照片失败，但继续删除宠物记录: {}", e.getMessage());
            }
        }
        
        // 删除宠物
        int result = petMapper.deleteById(petId);
        if (result != 1) {
            logger.error("删除宠物档案失败，宠物ID: {}", petId);
            throw new RuntimeException("删除宠物档案失败");
        }
        
        logger.info("用户ID: {} 删除宠物档案成功，宠物ID: {}", userId, petId);
    }
    
    @Override
    @Transactional
    public Pet updatePetPhoto(Long petId, MultipartFile photo, Long userId) throws IOException {
        // 验证参数
        if (petId == null || userId == null) {
            throw new IllegalArgumentException("宠物ID或用户ID不能为空");
        }
        
        if (photo == null || photo.isEmpty()) {
            throw new IllegalArgumentException("照片不能为空");
        }
        
        // 检查宠物是否存在且属于该用户
        Pet existingPet = petMapper.selectById(petId);
        if (existingPet == null) {
            logger.warn("宠物ID: {} 不存在", petId);
            throw new IllegalArgumentException("宠物不存在");
        }
        
        if (!existingPet.getUserId().equals(userId)) {
            logger.warn("用户ID: {} 无权访问宠物ID: {}", userId, petId);
            throw new SecurityException("无权限操作该宠物");
        }
        
        // 删除旧照片
        if (existingPet.getAvatar() != null) {
            fileUploadUtil.deleteImage(existingPet.getAvatar());
        }
        
        // 上传新照片并生成缩略图
        String fileName = fileUploadUtil.uploadImage(photo);
        String avatarUrl = fileUploadUtil.getFileAccessUrl(fileName);
        
        // 更新宠物头像
        Pet pet = new Pet();
        pet.setPetId(petId);
        pet.setAvatar(avatarUrl);
        pet.setUserId(userId); // 确保用户ID不会被修改
        pet.setUpdateTime(LocalDateTime.now());
        
        int result = petMapper.updateById(pet);
        if (result != 1) {
            logger.error("更新宠物照片失败，宠物ID: {}", petId);
            throw new RuntimeException("更新宠物照片失败");
        }
        
        logger.info("用户ID: {} 更新宠物照片成功，宠物ID: {}", userId, petId);
        
        return petMapper.selectById(petId);
    }
    
    @Override
    public List<PetListResponse> getPetList(Map<String, Object> params) {
        List<Pet> pets = petMapper.selectPage(params);
        List<PetListResponse> responses = new ArrayList<>();
        
        for (Pet pet : pets) {
            PetListResponse response = new PetListResponse();
            BeanUtils.copyProperties(pet, response);
            responses.add(response);
        }
        
        return responses;
    }
    
    /**
     * 检查宠物是否存在未完成业务
     * @param petId 宠物ID
     * @return 是否存在未完成业务
     */
    private boolean hasUnfinishedBusiness(Long petId){
        // 例如检查是否有未完成的订单、未完成的社交匹配等
        return false;
    }
    
    /**
     * 检查用户是否为宠物主人
     * @param petId 宠物ID
     * @param userId 用户ID
     * @return 是否为宠物主人
     */
    public boolean isPetOwner(Long petId, Long userId) {
        Pet pet = petMapper.selectById(petId);
        return pet != null && pet.getUserId().equals(userId);
    }
}
